package com.xxwy.sort.nlogn;

import com.xxwy.sort.Sort;

/**
 * @author xxwy
 * 自顶向下：的归并排序
 */
public class MergeSort implements Sort {

    @Override
    public void sort(int[] array, int n) {
        mergeSort(array, 0, n - 1);
    }

    /**
     * 递归使用归并排序arr[l...r]
     *
     * @param arr
     * @param l
     * @param r
     */
    private void mergeSort(int[] arr, int l, int r) {
        if (l >= r) {
            return;
        }
        int mid = (l + r) / 2;
        mergeSort(arr, l, mid);
        mergeSort(arr, mid+1, r);
        //有序的话就不merge了
        if(arr[mid] > arr[mid+1]) {
            merge(arr, l, mid, r);
        }
    }

    /**
     * arr[l...mid],arr[mid+1,r]两部分进行归并
     *
     * @param arr
     * @param l
     * @param mid
     * @param r
     */
    private void merge(int[] arr, int l, int mid, int r) {

        int aux[] = new int[r - l + 1];
        for (int i = l; i <= r; i++) {
            aux[i - l] = arr[i];
        }
        //两个子数组开头的位置
        int i = l;
        int j = mid + 1;
        //主要偏移量
        for (int k = l; k <= r; k++) {
            //i  / j 加到底了
            if (i > mid) {
                arr[k] = aux[j - l];
                j++;
            }
            else if (j > r) {
                arr[k] = aux[i - l];
                i++;
            }
            else if (aux[i - l] < aux[j - l]) {
                arr[k] = aux[i - l];
                i++;
            } else {
                arr[k] = aux[j - l];
                j++;
            }
        }


    }
}
